/**
 * 前面使用的redux都是独立的redux，与react没有一点关系，
 * 在使用的时候需要手动编写 Redux 存储订阅逻辑（手动调用dispath和getState、subscribe），这样做会变得非常重复。
 * React-redux官方文档：https://react-redux.js.org/introduction/why-use-react-redux
 * React-Redux 是 React 的官方 Redux UI 绑定库，用它处理存储交互逻辑，因此不必自己编写该代码（手动调用dispath和getState、subscribe）
 * 安装：npm install react-redux
 * 使用步骤：1.在index.js入口文件使用React-Redux导出的Provider包裹App组件 2.在用到store的地方使用connect包裹组件
 */

// 注意：查看本案例前确保index.js入口文件是：
// import { Provider } from "react-redux";
// import store from "./6.redux状态管理/6.react-redux/redux/store";
// <Provider store={store}>
//      <App />
// </Provider>

import React from "react";
import Home from "./Home";

import { connect } from "react-redux";

// 不需要再引入store对象，React-Redux 提供Provider组件，可以让容器组件拿到state
// import store from "./redux/store";

function App({ isShow, hide, show }) {
    // 不需要设置自己的状态来进行更新渲染和getState获取状态
    // const [isShow, setisShow] = useState(store.getState().HomeReducer.isShow);

    // 不需要手动subscribe订阅
    // useEffect(() => {
    //     store.subscribe(() => {
    //         setisShow(store.getState().HomeReducer.isShow);
    //     });
    // }, []);

    // const hide = () => {
    //     store.dispatch({
    //         type: "hide",
    //     });
    // };

    // const show = () => {
    //     store.dispatch({
    //         type: "show",
    //     });
    // };
    return (
        <div>
            {/* 只需直接调用该connect传来的props中的actionCreator
            不需要再dispatch(actionCreator)，dispatch操作完全由connect进行 */}
            <button onClick={hide}>隐藏标题</button>
            <button onClick={show}>显示标题</button>
            {isShow && <Home></Home>}
        </div>
    );
}

// React-Redux 提供connect方法，用于从 UI 组件生成容器组件。connect的意思，就是将这
//  两种组件连起来.
// connect是一个函数并且最后返回值也是一个函数，使用时：connect()(App)
// 意思是将App作为参数传给connect执行后返回的那个函数，并执行这个函数

// connect第一个参数是一个函数，该函数会接收store中所有的状态state作为参数
// 该函数必须返回一个对象，对象内根据需要添加需要向被包裹组件（App）传的状态
// 最终这个对象内的所有字段会以props的形式传给connect包裹的组件，并且它是响应式的，
// 当状态更新，connect会自动重新向包裹的组件传递props，以触发包裹的组件的更新渲染
// 这样被包裹的组件就不需要手动subscribe订阅和getState获取状态了，更不需要设置自己的状态来进行更新渲染了
const mapStateToProps = (state) => {
    console.log(state);
    return {
        isShow: state.HomeReducer.isShow,
    };
};

// connect第二个参数最终应是一个对象，里面包含被包裹组件需要使用的actionCreator（action创建者，即最终返回action的函数），
// 最终这个对象内的所有字段会以props的形式传给connect包裹的组件，并且它是响应式的，
// 被包裹组件只需直接调用该actionCreator，不需要再dispatch(actionCreator)，dispatch操作完全由connect进行
// mapDispatchToProps也可以是一个return对象的函数
const mapDispatchToProps = {
    hide() {
        return {
            type: "hide",
        };
    },
    show: () => {
        return {
            type: "show",
        };
    },
};
// connect(将来给孩子传的属性,将来给孩子传的回调函数)
export default connect(mapStateToProps, mapDispatchToProps)(App);

// UI组件和容器组件
// （1）UI组件 （如这里的App组件）
// •只负责 UI 的呈现，不带有任何业务逻辑
// •没有状态（即不使用this.state这个变量）
// •所有数据都由参数（this.props）提供
// •不使用任何 Redux 的 API
//  (2) 容器组件（如经过connect转化后的App，App组件最终的形态）
// •负责管理数据和业务逻辑，不负责 UI 的呈现
// •带有内部状态
// •使用 Redux 的 API

// connect()(App)和withRouter(App)一样都是高阶组件：获取低阶组件，生成高阶组件
//（比如这里App组件就是一个低级的组件，通过connect转化后变为了高级组件）
